package com.cqyanyu.yanyu.http;

import com.cqyanyu.yanyu.utils.XFileUtil;
import com.orhanobut.logger.Logger;

import org.json.JSONException;
import org.json.JSONObject;
import org.xutils.HttpManager;
import org.xutils.common.Callback;
import org.xutils.common.util.KeyValue;
import org.xutils.http.HttpMethod;
import org.xutils.http.HttpTask;
import org.xutils.http.RequestParams;
import org.xutils.http.app.RequestTracker;
import org.xutils.http.request.UriRequest;
import org.xutils.x;

import java.lang.reflect.Type;

/**
 * Created by wyouflf on 15/7/23.
 * HttpManager实现
 */
public final class XHttpManagerImpl implements HttpManager {

    private static final Object lock = new Object();
    private static volatile XHttpManagerImpl instance;

    private XHttpManagerImpl() {
    }

    public static void registerInstance() {
        if (instance == null) {
            synchronized (lock) {
                if (instance == null) {
                    instance = new XHttpManagerImpl();
                }
            }
        }
        x.Ext.setHttpManager(instance);
    }

    @Override
    public <T> Callback.Cancelable get(RequestParams entity, Callback.CommonCallback<T> callback) {
        setRequestParams(entity);
        return request(HttpMethod.GET, entity, callback);
    }

    @Override
    public <T> Callback.Cancelable post(RequestParams entity, Callback.CommonCallback<T> callback) {
        setRequestParams(entity);
        return request(HttpMethod.POST, entity, callback);
    }

    @Override
    public <T> Callback.Cancelable request(HttpMethod method, RequestParams entity, Callback.CommonCallback<T> callback) {
        entity.setMethod(method);
        Callback.Cancelable cancelable = null;
        if (callback instanceof Callback.Cancelable) {
            cancelable = (Callback.Cancelable) callback;
        }
        HttpTask<T> task = new HttpTask<T>(entity, cancelable, callback);
        return x.task().start(task);
    }

    @Override
    public <T> T getSync(RequestParams entity, Class<T> resultType) throws Throwable {
        return requestSync(HttpMethod.GET, entity, resultType);
    }

    @Override
    public <T> T postSync(RequestParams entity, Class<T> resultType) throws Throwable {
        return requestSync(HttpMethod.POST, entity, resultType);
    }

    @Override
    public <T> T requestSync(HttpMethod method, RequestParams entity, Class<T> resultType) throws Throwable {
        DefaultSyncCallback<T> callback = new DefaultSyncCallback<T>(resultType);
        return requestSync(method, entity, callback);
    }

    @Override
    public <T> T requestSync(HttpMethod method, RequestParams entity, Callback.TypedCallback<T> callback) throws Throwable {
        entity.setMethod(method);
        HttpTask<T> task = new HttpTask<T>(entity, null, callback);
        return x.task().startSync(task);
    }

    private void setRequestParams(RequestParams entity) {
        entity.setCacheDirName(XFileUtil.getCacheDownloadDir(x.app()));//设置缓存目录
        entity.setConnectTimeout(5000);//超时时间
        entity.setCacheMaxAge(36000);
        if (x.isDebug()) {
            entity.setRequestTracker(new RequestTracker() {
                @Override
                public void onWaiting(RequestParams params) {

                }

                @Override
                public void onStart(RequestParams params) {

                }

                @Override
                public void onRequestCreated(UriRequest request) {

                }

                @Override
                public void onCache(UriRequest request, Object result) {

                }

                @Override
                public void onSuccess(UriRequest request, Object result) {
                    if (result instanceof java.lang.String) {
                        XResultNoData xResultNoData = new XResultNoData((String) result);
//                        Logger.t("URL").d(request.getRequestUri(), result);
                        if (request.getResponseHeaders() != null) {
                            JSONObject jsonObject = new JSONObject();
                            for (KeyValue keyValue : request.getParams().getBodyParams()) {
                                try {
                                    jsonObject.put(keyValue.key, keyValue.value);
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }
                            Logger.t("Headers").json(jsonObject.toString());
                        }
                        Logger.t("Request").json((String) result);

                    } else {
                        Logger.d(request.getRequestUri(), result);
                    }

                }

                @Override
                public void onCancelled(UriRequest request) {

                }

                @Override
                public void onError(UriRequest request, Throwable ex, boolean isCallbackError) {

                }

                @Override
                public void onFinished(UriRequest request) {

                }
            });
        }

    }

    private class DefaultSyncCallback<T> implements Callback.TypedCallback<T> {

        private final Class<T> resultType;

        public DefaultSyncCallback(Class<T> resultType) {
            this.resultType = resultType;
        }

        @Override
        public Type getLoadType() {
            return resultType;
        }

        @Override
        public void onSuccess(T result) {

        }

        @Override
        public void onError(Throwable ex, boolean isOnCallback) {

        }

        @Override
        public void onCancelled(CancelledException cex) {

        }

        @Override
        public void onFinished() {

        }
    }
}
